#include "kit/coordinator/Coordinator.hpp"
#include "kit/user/User.hpp"
#include <vector>
#include <string>

namespace KitCoordinator
{
	void Coordinator::runThreadImpl()
	{
		// this variable contains the sequence value of expected event
		while(1)
		{
			// if someone killed this event then exit but only
			// when we processed all events from the queue
			if(!isAlive() && _eventQueue->empty())
				Thread::exit();
			// firstly process queue
			processQueue();
		}
	}

	void Coordinator::processQueue()
	{
		unsigned int aElementsItr = 0;
		// if there is something in the queue process it
		while(!_eventQueue->empty() && aElementsItr <= MAX_EVENTS_AT_TIME)
		{
			KitEvent::Event * aNewEvent = _eventQueue->pop();
			// if the sequence number of the event is expected
			if(_seq.getExpectedNo() == aNewEvent->getMessage()->getSequenceNo())
			{
				// execute the event and remove it from processing
				aNewEvent->execute(_userMap);
				delete aNewEvent;
				_seq.increment();
			}
			else if(aNewEvent->isValid(_userMap))
			{
				// add it back to the queue, as it's time will come ;)
				// keep in mind we are adding back to the queue event
				// that have active users present.
				_eventQueue->push(aNewEvent);
			}
			else
			{
				// if sequence number is not correct and we don't have
				// users related to the event, we may just get rid off it.
				// But we also need to remember to skip its sequence number
				// while processing.
				_seq.addToSkip(aNewEvent->getMessage()->getSequenceNo());
				delete aNewEvent;
			}

			++aElementsItr;
		}
	}
}
